#ifdef __UX_STL_UNIT_TEST__

#include "../ux_stl_ext.h"

using namespace UX_STL;
using namespace ALShell;



void SineWave ()
{
	ALSoundBufferPtr	buf = new ALSoundBuffer();
	ALSoundPtr			snd = null;
	
	const uint	freq		= 44000;
	const float	wave_freq	= 1000.0f;
	const float	period		= float(freq) / wave_freq / 2.0f;
	
	binary_array_t	snd_data;
	snd_data.Resize( 1<<17 );
	
	FOR( i, snd_data )
	{
		snd_data[i] = uint8( ( Sin( float(i) * Pi<float>() / period ) * 0.5f + 0.5f ) * 255.0f );
	}

	CHECK_ERR( buf->Create( snd_data.ptr(), snd_data.Size(), al_format::MONO_8, freq, 1.0f, 1.0f, true ), void() );
	CHECK_ERR( buf->CreateSound( snd ), void() );

	WARNING( (string() << "sound duration: " << buf->Time()).cstr() );

	snd->Play();

	while (true) {}
	//while ( snd->GetState() == al_sound_state::PLAYING ) {}
}


void SineWave2 ()
{
	ALSoundBufferPtr	buf = new ALSoundBuffer();
	ALSoundPtr			snd = null;
	
	const uint	freq		= 44000;
	const float	wave_freq0	= 1000.0f;
	const float	wave_freq1	= 100.0f;
	const float	period0		= float(freq) / wave_freq0 / 2.0f;
	const float	period1		= float(freq) / wave_freq1 / 2.0f;
	
	binary_array_t	snd_data;
	snd_data.Resize( 1<<17 );
	
	FOR( i, snd_data )
	{
		float w0 = Sin( float(i) * Pi<float>() / period0 );
		float w1 = Sin( float(i) * Pi<float>() / period1 );

		snd_data[i] = uint8( ( ( w0 - w1 ) * 0.5f + 0.5f ) * 255.0f );
	}

	CHECK_ERR( buf->Create( snd_data.ptr(), snd_data.Size(), al_format::MONO_8, freq, 1.0f, 1.0f, true ), void() );
	CHECK_ERR( buf->CreateSound( snd ), void() );

	WARNING( (string() << "sound duration: " << buf->Time()).cstr() );

	snd->Play();

	while (true) {}
	//while ( snd->GetState() == al_sound_state::PLAYING ) {}
}


void SawWave ()
{
	ALSoundBufferPtr	buf = new ALSoundBuffer();
	ALSoundPtr			snd = null;
	
	const uint	freq		= 44000;
	const float	wave_freq	= 1000.0f;
	const float	period		= float(freq) / wave_freq;
	
	binary_array_t	snd_data;
	snd_data.Resize( 1<<17 );

	uint	c = 0;
	
	FOR( i, snd_data )
	{
		if ( c >= period )
			c = 0;

		const float	f = ( c / period );

		snd_data[i] = uint8( f * 255.0f );
		c++;
	}
	
	CHECK_ERR( buf->Create( snd_data.ptr(), snd_data.Size(), al_format::MONO_8, freq, 1.0f, 1.0f, false ), void() );
	CHECK_ERR( buf->CreateSound( snd ), void() );

	WARNING( (string() << "sound duration: " << buf->Time()).cstr() );

	snd->Play();

	//while (true) {}
	while ( snd->GetState() == al_sound_state::PLAYING ) {}
}


void TriangleWave ()
{
	ALSoundBufferPtr	buf = new ALSoundBuffer();
	ALSoundPtr			snd = null;
	
	const uint	freq		= 44000;
	const float	wave_freq	= 1000.0f;
	const float	period		= float(freq) / wave_freq / 2.0f;
	
	binary_array_t	snd_data;
	snd_data.Resize( 1<<17 );

	int		c = int( period * 2 );
	int		c2 = -1;
	float	sr_2m = period;
	float	sr = float(freq) / wave_freq / 4.0f;
	
	FOR( i, snd_data )
	{
		if ( c > sr_2m ) {
			c  = (int) sr_2m;
			c2 = -1;
		}

		if ( c < 0 ) {
			c  = 0;
			c2 = 1;
		}

		const float	f = ( c / sr ) * 0.5f;

		snd_data[i] = uint8( f * 255.0f );

		c += c2;
	}
	
	CHECK_ERR( buf->Create( snd_data.ptr(), snd_data.Size(), al_format::MONO_8, freq, 1.0f, 1.0f, false ), void() );
	CHECK_ERR( buf->CreateSound( snd ), void() );

	WARNING( (string() << "sound duration: " << buf->Time()).cstr() );

	snd->Play();

	//while (true) {}
	while ( snd->GetState() == al_sound_state::PLAYING ) {}
}


void GenerateAndPlaySound ()
{
	ALSoundSystem		sound_sys;

	CHECK_ERR( sound_sys.Init(), void() );

	sound_sys.MakeCurrent();

	//SineWave();
	SineWave2();
	//SawWave();
	//TriangleWave();

	/*binary_array_t	snd_data;
	uint			freq		= 44000;
	uint			mono_freq	= 18000;

	snd_data.Resize( 1<<17 );
	/*
	ZeroMem( snd_data.ptr(), snd_data.Size() );

	for (uint i = mono_freq; i < snd_data.Count(); i += freq)
	{
		snd_data[i] = 255;
	}*/

	//uint	value		= 255;
	//float	period		= 1.0f;

	/*
	while ( true )
	{
		FOR( i, snd_data )
		{
			//float	f = Sin( float(i) * Pi<float>() * period ) * 1.0e5f;
			//snd_data[i] = uint8( Abs(f) * 255.0f );

			//snd_data[i] = ( i % 10 == 0 ? value : 0 );

			// sine
			//snd_data[i] = uint8( Abs( Sin( float(i) * Pi<float>() / period ) ) * 255.0f );
		}

		CHECK_ERR( buf->Create( snd_data.ptr(), snd_data.Size(), al_format::MONO_8, freq, 1.0f, 1.0f, true ), );
		CHECK_ERR( buf->CreateSound( snd ), );

		WARNING( (string() << "period: " << period << " sound duration: " << buf->Time()).cstr() );

		snd->Play();


		while ( snd->GetState() == al_sound_state::PLAYING )
		{
		}

		period += 1.0f;

		snd = null;
		buf->Destroy();
	}*/
}


extern void SoundGen_Test ()
{
	GenerateAndPlaySound();
}


#endif	// __UX_STL_UNIT_TEST__